/**
 * _c解析标签
 * _v解析模板语法
 * _s解析状态数据
 * return _c('div', {id: app}, _v('hello' + _s(msg)));
 */
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;

export function generate(ast) {
  let children = genChildren(ast);
  let code = `_c(${JSON.stringify(ast.tag)}, ${ast.attrs.length ? genPorps(ast.attrs) : 'null'},
  ${children && children})`;
  return code;
}

function genPorps(attrs) {
  let str = "";
  attrs.forEach(item => {
    if (item.name === 'style') {
      let ary = item.value.split(";").filter(ls => ls);
      let obj = {};
      ary.forEach(ls => {
        let arr = ls.split(":");
        obj[arr[0].trim()] = arr[1].trim();
      })
      item.value = obj;
    }
    str += `${item.name}:${JSON.stringify(item.value)},`;
  })
  str = str.slice(0, -1); // 截掉最后一个逗号
  let finalStr = `{${str}}`
  return finalStr;
}

function genChildren(ast) {
  let children = ast.children;
  if (children) {
    return children.map(child => gen(child)).join(',');
  }
}

function gen(child) {
  if (child.type === 1) { // 元素
    return generate(child);
  } else {
    let text = child.text;
    if (!defaultTagRE.test(text)) { // 只是文本
      return `_v(${JSON.stringify(text)})`;
    }
    // 有插值表达式
    let tokens = [];
    // 对于test方法，使用完一次后需要置为0，不然首次有效，第二次再执行就不行了
    let lastIndex = defaultTagRE.lastIndex = 0;
    let match;
    while (match = defaultTagRE.exec(text)) {
      let index = match.index;
      if (index > lastIndex) {
        tokens.push(JSON.stringify(text.slice(lastIndex, index)));
      }
      tokens.push(`_s(${match[1].trim()})`);
      lastIndex = index + match[0].length;
    }
    if (lastIndex < text.length) {
      tokens.push(JSON.stringify(text.slice(lastIndex)));
    }
    return `_v(${tokens.join("+")})`;
  }
}